#include <iostream>
#include <fstream>
#include <google/protobuf/unknown_field_set.h>
#include "contacts.pb.h"


using namespace std;
using namespace c_contacts;
using namespace google::protobuf;

void PrintfContacts(const Contacts& contacts)
{
    for(int i = 0; i < contacts.contacts_size(); i++)
    {
        const PeopleInfo& people = contacts.contacts(i);

        cout << "------------联系⼈" << i+1 << "------------" << endl;
        cout << "姓名：" << people.name() << endl;
        cout << "年龄：" << people.age() << endl;
        int j = 1;

        for (const PeopleInfo_Phone& phone : people.phone())
        {
            cout <<  "电话" << j++ << ": " << phone.number() << endl;
        }

        if(1)// 打印未知字段
        {
            // 1. 通过消息对象获取反射接口
            //    注意这里必须是对象 people 调用，而不是类名 PeopleInfo
            const Reflection* reflection = people.GetReflection();

            // 2. 获取 "未知字段集合"
            //    如果解析到了 proto 文件里没定义的字段，它们就会存在这里
            const UnknownFieldSet& unknownSet = reflection->GetUnknownFields(people);

            // 3. 遍历 UnknownFieldSet 里的每一个未知字段
            for (int j = 0; j < unknownSet.field_count(); j++) 
            {
                // field(j) 返回的是 UnknownField，而不是 UnknownFieldSet
                const UnknownField& unknown_field = unknownSet.field(j);

                // 打印字段的编号和类型
                std::cout << "未知字段 " << j+1
                        << " : 字段编号: " << unknown_field.number()
                        << " 类型: " << unknown_field.type();

                // 4. 根据类型取出具体的值
                switch (unknown_field.type()) {
                    case UnknownField::TYPE_VARINT:
                        // varint 类型的未知字段（int64/uint64/bool 等）
                        std::cout << " 值: " << unknown_field.varint() << std::endl;
                        break;
                    case UnknownField::TYPE_LENGTH_DELIMITED:
                        // length-delimited 类型（string / bytes / 嵌套 message）
                        std::cout << " 值: " << unknown_field.length_delimited() << std::endl;
                        break;
                    default:
                        std::cout << " [未处理的类型]" << std::endl;
                        break;
                }
            }
        }

        
    }
}

int main(int argc,char* argv[])
{
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    
    if(argc!=2)
    {
        cerr << "Usage:  " << argv[0] << "CONTACTS_FILE" << endl;
        return -1;
    }
    
    // 以⼆进制⽅式读取 contacts
    Contacts contacts;
    fstream input(argv[1], ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input))
    {
        cerr << "Failed to parse contacts." << endl;
        input.close();
        return -1;
    }

    PrintfContacts(contacts);

    input.close();
    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}